<template>
</template>
<script lang="ts">
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import GUI from 'three/examples/jsm/libs/lil-gui.module.min.js';
import { EffectComposer, GammaCorrectionShader, GlitchPass, OutlinePass, RenderPass, ShaderPass, UnrealBloomPass } from 'three/examples/jsm/Addons.js';



const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 100);
camera.position.set(0, 0, 6);

const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);

const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;

scene.add(new THREE.AmbientLight(0xffffff, 0.5));
const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);
dirLight.position.set(5, 5, 5);
scene.add(dirLight);

// 物体
const sphere = new THREE.Mesh(
    new THREE.SphereGeometry(1, 32, 32),
    new THREE.MeshStandardMaterial({ color: 0x33ccff })
);
scene.add(sphere);

const box = new THREE.Mesh(
    new THREE.BoxGeometry(1, 1, 1),
    new THREE.MeshStandardMaterial({ color: 0xff8844 })
);
box.position.set(2.5, 0, 0);
scene.add(box);

const torus = new THREE.Mesh(
    new THREE.TorusKnotGeometry(0.6, 0.2, 100, 16),
    new THREE.MeshStandardMaterial({ color: 0x88ff88 })
);
torus.position.set(-2.5, 0, 0);
scene.add(torus);

const selectable = [sphere, box, torus];

// 后处理
const composer = new EffectComposer(renderer);
composer.addPass(new RenderPass(scene, camera));

const outlinePass = new OutlinePass(
    new THREE.Vector2(window.innerWidth, window.innerHeight),
    scene,
    camera
);
outlinePass.edgeStrength = 3.0;
outlinePass.edgeGlow = 1.0;
outlinePass.edgeThickness = 1.5;
outlinePass.visibleEdgeColor.set('#00ffff');
outlinePass.hiddenEdgeColor.set('#000000');
outlinePass.selectedObjects = [sphere];
composer.addPass(outlinePass);

const bloomPass = new UnrealBloomPass(
    new THREE.Vector2(window.innerWidth, window.innerHeight),
    0.6,  // strength
    0.4,  // radius
    0.85  // threshold
);
composer.addPass(bloomPass);

const gammaPass= new ShaderPass(GammaCorrectionShader);
composer.addPass(gammaPass);


// 3. 设置glitchPass通道
const glitchPass = new GlitchPass();
// composer.addPass(glitchPass);

// 鼠标点击选择
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();

window.addEventListener('click', (event) => {
    const rect = renderer.domElement.getBoundingClientRect();
    mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
    mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;
    raycaster.setFromCamera(mouse, camera);
    const intersects = raycaster.intersectObjects(selectable);
    if (intersects.length > 0) {
        outlinePass.selectedObjects = [intersects[0].object];
    }
});

// dat.GUI 控制面板
const gui = new GUI();
const bloomFolder = gui.addFolder('Bloom');
bloomFolder.add(bloomPass, 'strength', 0, 3).name('Strength');
bloomFolder.add(bloomPass, 'radius', 0, 1).name('Radius');
bloomFolder.add(bloomPass, 'threshold', 0, 1).name('Threshold');
bloomFolder.open();

const outlineFolder = gui.addFolder('Outline');
const outlineParams = {
    color: '#00ffff',
    thickness: 1.5,
    strength: 3.0,
    glow: 1.0
};
outlineFolder.addColor(outlineParams, 'color').name('Edge Color').onChange(val => {
    outlinePass.visibleEdgeColor.set(val);
});
outlineFolder.add(outlineParams, 'thickness', 0.1, 4).onChange(val => outlinePass.edgeThickness = val);
outlineFolder.add(outlineParams, 'strength', 0, 5).onChange(val => outlinePass.edgeStrength = val);
outlineFolder.add(outlineParams, 'glow', 0, 5).onChange(val => outlinePass.edgeGlow = val);
outlineFolder.open();

// 渲染循环
function animate() {
    requestAnimationFrame(animate);
    controls.update();
    composer.render();
}
animate();

window.addEventListener('resize', () => {
    const w = window.innerWidth;
    const h = window.innerHeight;
    camera.aspect = w / h;
    camera.updateProjectionMatrix();
    renderer.setSize(w, h);
    composer.setSize(w, h);
});
</script>